
import 'package:flutter/material.dart';
import 'package:flutter_common/flutter_common.dart';
import 'package:flutter_common/util/context_extension.dart';
import 'package:flutter_common/util/toast_util.dart';

const int BtnOk = 1;
const int BtnCancel = 2;

///[outsideCancel] 是否可以通过安卓返回键或者遮挡层关闭弹框
Future showAlertDialog(BuildContext context, String content,
    {bool outsideCancel = true,
    String title = '',
    String btnText = "我知道了",
    VoidCallback? onPressed}) {
  return showAlertDialog2(context, content: content, title: title, btnText: btnText, onPressed: onPressed, outsideCancel: outsideCancel);
}

Future showAlertDialog2(BuildContext context,
    {bool outsideCancel = true,
      String? content,
      InlineSpan? richContent,
    String title = '',
    String btnText = "我知道了",
    VoidCallback? onPressed}) {
  return showDialog(
      context: context,
      barrierDismissible: outsideCancel,
      routeSettings: const RouteSettings(name: "dialog"),
      builder: (context) =>
          FxAlertDialog(title, content, richContent, btnText, onPressed, outsideCancel));
}

///[outsideCancel] 是否可以通过安卓返回键或者遮挡层关闭弹框
Future showConfirmDialog(BuildContext context, String content,
    {bool outsideCancel = true,
    String title = '',
    String cancelText = "取消",
    String okText = "确定",
    VoidCallback? onCancelPressed,
    VoidCallback? onOkPressed,
    VoidCallback? onDismiss}) {
  return showConfirmDialog2(context,
      outsideCancel: outsideCancel,
      title: title,
      content: content,
      okText: okText,
      cancelText: cancelText,
      onOkPressed: onOkPressed,
      onCancelPressed: onCancelPressed,
      onDismiss: onDismiss);
}

Future showConfirmDialog2(BuildContext context,
    {bool outsideCancel = true,
      String? content,
      InlineSpan? richContent,
    String title = '',
    String cancelText = "取消",
    String okText = "确定",
    VoidCallback? onCancelPressed,
    VoidCallback? onOkPressed,
    VoidCallback? onDismiss}) {
  return showDialog(
      context: context,
      barrierDismissible: outsideCancel,
      routeSettings: const RouteSettings(name: "dialog"),
      builder: (context) => FxConfirmDialog(title, content, richContent, okText, cancelText,
          onOkPressed, onCancelPressed, outsideCancel)).then((value) {
    if (onDismiss != null) onDismiss();
    return value;
  });
}

///[outsideCancel] 是否可以通过安卓返回键或者遮挡层关闭弹框
///
///[emptyInput] 输入框内容是否不能为空
///
/// [validator] 输入框验证，返回true表示验证通过，false表示验证不通过
Future showInputDialog(BuildContext context, {bool outsideCancel = true,
  String title = '',
  String? subTitle,
  String content = '',
  String? hint,
  String? tips,
  TextInputType? keyboardType,
  String cancelText = "取消",
  String okText = "确定",
  bool emptyInput = true,
  VoidCallback? onCancelPressed,

  bool Function(String)? validator,
  int maxLine = 1,
  int? maxLength,
  void Function(String)? onOkPressed}) {
  return showDialog(
      context: context,
      barrierDismissible: outsideCancel,
      routeSettings: const RouteSettings(name: "dialog"),
      builder: (context) =>
          FxInputDialog(
            title,
            content,
            okText,
            cancelText,
            keyboardType,
            onOkPressed,
            onCancelPressed,
            outsideCancel,
            emptyInput,
            hint,
            validator,
            tips,
            maxLine,
            maxLength,
            subTitle: subTitle,
          ));
}


class FxAlertDialog extends StatelessWidget {

  final String title;
  final String? content;
  final InlineSpan? richContent;
  final String btnText;
  final bool outsideCancel;
  final VoidCallback? btnPressed;
  final double contentMarginBottom;

  const FxAlertDialog(this.title, this.content, this.richContent, this.btnText, this.btnPressed,
      this.outsideCancel, {Key? key, this.contentMarginBottom = 30}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    double dialogWidth = MediaQuery.of(context).size.width - 81; //dialog两边的空白是40,1是中间线的宽度
    List<Widget> children = [];
    children.add(Container(height: 30));
    if (title.isNotEmpty) {
      children.add(buildTitle(context));
      children.add(Container(height: 10));
    }
    children.add(buildContent(context));
    List<Widget> w = extrasWidget(context);
    if (w.isNotEmpty) {
      children.add(Container(height: 10));
      children.addAll(w);
    }
    children.add(SizedBox(height: contentMarginBottom));
    children.add(FxTheme().line);
    //400 是pad上允许最大的宽度
    children.add(buildButton(context, dialogWidth > 400 ? 399 : dialogWidth));

    Widget body = Center(
        child: Material(
            color: Colors.transparent,
            child: Container(
                margin: const EdgeInsets.symmetric(horizontal: 40),
                constraints: const BoxConstraints(minWidth: 280, maxWidth: 400),
                decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(5)),
                child: Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: children))));
    if (!outsideCancel) {
      body = WillPopScope(child: body, onWillPop: () => Future.value(false));
    }
    return body;
  }

  buildTitle(BuildContext context) => Text(title,
      textAlign: TextAlign.center,
      style: const TextStyle(
          color: Color(0xff333333), fontSize: 15, fontWeight: FontWeight.bold));

  buildContent(BuildContext context) {
    Widget child;
    if (richContent != null) {
      child = RichText(text: richContent!);
    } else {
      child = Text(content!,
          style: const TextStyle(color: Color(0xff666666), fontSize: 14));
    }
    return Padding(
        padding: const EdgeInsets.fromLTRB(15, 0, 15, 0), child: child);
  }

  ///添加其他不同的组件
  List<Widget> extrasWidget(BuildContext context) => [];

  ///构建底部的弹框按钮
  ///
  ///[width] 底部按钮所占的宽度
  buildButton(BuildContext context, double width) => singleButton(context, btnText, btnPressed, FxTheme().buttonColor, BtnOk, width);

  singleButton(BuildContext context, String text, VoidCallback? callback,Color color, int value, double width) {
    return TextButton(
        onPressed: () {
          onButtonPressed(context, value, callback);
        },
        style: TextButton.styleFrom(minimumSize: Size(width, 46)),
        child: Text(
          text,
          style: TextStyle(fontSize: 14, color: color),
        ));
  }

  onButtonPressed(BuildContext context, int value, VoidCallback? callback) {
    Navigator.pop(context, value);
    callback?.call();
  }
}

class FxConfirmDialog extends FxAlertDialog {
  final String cancelText;
  final VoidCallback? cancelPressed;

  const FxConfirmDialog(
    String title,
    String? content,
    InlineSpan? richContent,
    String okText,
    this.cancelText,
    VoidCallback? okPressed,
    this.cancelPressed,
    bool outsideCancel, {
    Key? key,
    double contentMarginBottom = 30,
  }) : super(title, content, richContent, okText, okPressed, outsideCancel,
            key: key, contentMarginBottom: contentMarginBottom);

  @override
  buildButton(BuildContext context, double width) => Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          singleButton(context, cancelText, cancelPressed, const Color(0xff999999), BtnCancel, width / 2),
          SizedBox(height: 45, child: FxTheme().vLine, width: 0.51),
          buildOkButton(context, width /2)
        ],
      );

  buildOkButton(BuildContext context, double width) => singleButton(context, btnText, btnPressed, FxTheme().buttonColor, BtnOk, width);
}

class FxInputDialog extends StatefulWidget {
  final String? hint;
  final String? subTitle;
  final String? tips;
  final String title;
  final String content;
  final bool emptyInput;
  final bool outsideCancel;
  final int maxLine;
  final int? maxLength;
  final TextInputType? keyboardType;
  final void Function(String)? okPressed;
  final VoidCallback? cancelPressed;
  final bool Function(String)? validator;
  final String okText;
  final String cancelText;

  const FxInputDialog(
      this.title,
      this.content,
      this.okText,
      this.cancelText,
      this.keyboardType,
      this.okPressed,
      this.cancelPressed,
      this.outsideCancel,
      this.emptyInput,
      this.hint,
      this.validator,
      this.tips,
      this.maxLine,
      this.maxLength,{super.key,this.subTitle});

  @override
  State<StatefulWidget> createState() => _FxInputState();
}

class _FxInputState extends State<FxInputDialog> {

  TextEditingController controller = TextEditingController();

  @override
  void initState() {
    super.initState();
    controller.text = widget.content;
    controller.selection = TextSelection.fromPosition(TextPosition(offset: widget.content.length));
  }

  @override
  Widget build(BuildContext context) {
    return _FxInputDialog(
        widget.title,
        widget.okText,
        widget.cancelText,
        widget.okPressed,
        widget.cancelPressed,
        widget.outsideCancel,
        widget.emptyInput,
        widget.validator,
        widget.hint,
        widget.keyboardType,
        widget.tips,
        widget.maxLine,
        widget.maxLength,
        widget.subTitle,
        controller);
  }
}

class _FxInputDialog extends FxConfirmDialog {

  final String? hint;
  final String? subTitle;
  final String? tips;
  final bool emptyInput;
  final int maxLine;
  final int? maxLength;
  final TextInputType? keyboardType;
  final TextEditingController controller;
  final void Function(String)? okPressed;
  final bool Function(String)? validator;

  const _FxInputDialog(
      String title,
      String okText,
      String cancelText,
      this.okPressed,
      VoidCallback? cancelPressed,
      bool outsideCancel,
      this.emptyInput,
      this.validator,
      this.hint,
      this.keyboardType,
      this.tips,
      this.maxLine,
      this.maxLength, this.subTitle, this.controller)
      : super(title, '', null, okText, cancelText, null, cancelPressed,
      outsideCancel,contentMarginBottom: 15);

  @override
  Widget buildContent(BuildContext context) {
    return Column(mainAxisSize: MainAxisSize.min, children: [
      if (subTitle?.isNotEmpty == true) ...[
        Text(
          subTitle!,
          softWrap: true,
          style:
          TextStyle(fontSize: fontSize28, color: const Color(0xff999999)),
        ),
        const SizedBox(height: 8),
      ],
      Padding(
          padding: const EdgeInsets.fromLTRB(15, 0, 15, 0),
          child: ClipRRect(
              borderRadius: const BorderRadius.all(Radius.circular(6)),
              clipBehavior: Clip.antiAlias,
              child: TextField(
                  controller: controller,
                  maxLines: maxLine,
                  maxLength: maxLength,
                  keyboardType: keyboardType,
                  style: TextStyle(
                      fontSize: fontSize30, color: const Color(0xff333333)),
                  textInputAction: TextInputAction.done,
                  decoration: InputDecoration(
                    hintText: hint,
                    hintStyle: TextStyle(
                        fontSize: fontSize30, color: const Color(0xffcccccc)),
                    fillColor: const Color(0xffF6F6F6),
                    filled: true,
                    focusedBorder: OutlineInputBorder(
                      borderRadius:
                      const BorderRadius.all(Radius.circular(6)),
                      borderSide: BorderSide(color: FxTheme().buttonColor),
                    ),
                    contentPadding: const EdgeInsets.fromLTRB(15, 12, 15, 12),
                    //不起作用
                    border: const OutlineInputBorder(
                      borderSide:
                      BorderSide(color: Colors.transparent, width: 1),
                      borderRadius: BorderRadius.all(Radius.circular(6)),
                    ),
                    //可输入、未获取焦点时 默认边框
                    enabledBorder: const OutlineInputBorder(
                        borderSide:
                        BorderSide(color: Colors.transparent, width: 1),
                        borderRadius:
                        BorderRadius.all(Radius.circular(6))),
                  ))))
    ]);
  }

  @override
  buildOkButton(BuildContext context, double width){
    return TextButton(
        onPressed: () {
          if(!emptyInput && controller.text.isEmpty) {
            ToastUtil.errorToast(tips??hint??"输入框内容不能为空");
            return;
          }
          if(validator != null && validator!(controller.text) == false) {
            return;
          }
          Navigator.pop(context, BtnOk);
          okPressed?.call(controller.text);
        },
        style: TextButton.styleFrom(minimumSize: Size(width, 46)),
        child: Text(btnText, style: TextStyle(fontSize: 14, color: FxTheme().buttonColor))
    );
  }
}